 
/**
 * 
 */
package com.txby.platformApi.component.service;

import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.jck.common.util.BeanToMapUtil;
import com.jck.mybatis.mapper.MybatisBaseDaoCRUD;
import com.jck.tools.ArithSolve;
import com.txby.alipay.AlipayTradeUtil;
import com.txby.pf.common.utils.R;
import com.txby.pf.common.utils.SpringContextUtils;
import com.txby.platformCore.component.service.GlobalLogAspectInterceptor;
import com.txby.platformCore.component.util.MakeOrderNumUtil;
import com.txby.platformCore.data.shop.AliOrderQueryCusReturnModel;
import com.txby.platformCore.data.shop.AliRefundCusReturnModel;
import com.txby.platformCore.data.shop.WxOrderQueryCusReturnModel;
import com.txby.platformCore.data.shop.WxRefundCusReturnModel;
import com.txby.platformCore.entity.shop.GoodsOrders;
import com.txby.platformCore.entity.shop.ShopsThirdGoodsRefund;
import com.txby.platformCore.entity.shop.ShopsThirdPayOrder;
import com.txby.platformCore.entity.shop.ShopsThirdPayOrderRecord;
import com.txby.wxpay.WXRefundModel;
import com.txby.wxpay.WxTradeUtil;

/**
 * @author Administrator
 *
 */

@Service
public class PayOrderRefundService extends MybatisBaseDaoCRUD {
	@Resource
	private GlobalLogAspectInterceptor gla;
 /**
  * 商品下单
 * @Title: saveGoodsBuy2Orders 
 * @param @param goods
 * @param @param goodsInfoJson
 * @param @return
 * @param @throws ParseException    设定文件 
 * @return String    返回类型 
 * @throws
  */
	@Transactional(propagation = Propagation.REQUIRED,timeout=36000,rollbackFor=Exception.class)
	public R exceuteRefund(Long orderId){
		String sql=" SELECT stpo.totalMoney,stpo.outTradeNo,stgr.id_ refundId, stpo.collectionMethod,stgr.refundFee,stgr.refundStatus,stgr.createTime,go.ordersStatus,gor.goodsTypeId,gor.goodsName,go.id_ ordersId,go.goodsTotalMoney,go.lastTotalMoney,go.isVisitor,go.sickId,go.outOrderNo,go.receiveAddressFull,go.receiveMobileNO,"
				+ " go.receiveName, gor.goodsId, gor.goodsNum, gor.price, sp.name spName FROM t_txby_sp_goodsOrdersRelation gor INNER JOIN t_txby_sp_goodsOrders go ON go.id_ = gor.ordersId INNER JOIN t_txby_sp_shopsThirdPayOrderRelation stpor INNER JOIN t_txby_sp_shopsThirdPayOrder stpo ON stpor.shopsThirdPayOrderId = stpo.id_"
				+ " AND stpor.ordersId = go.id_ INNER JOIN t_txby_sp_shopsThirdGoodsRefund stgr ON stgr.shopsThirdPayOrderId = stpo.id_ AND stgr.ordersId = go.id_ INNER JOIN t_txby_sp_shops sp ON sp.id_ = gor.shopsId INNER JOIN sys_dept d ON d.dept_id = sp.deptId WHERE go.id_="+orderId+" ";
		  Map data=(Map) this.findBySqlUniqueObject(sql, null, null);
		  if(data!=null){
			  Long ordersId=new Long(data.get("ordersId").toString());
			  Long refundId=new Long(data.get("refundId").toString());
			  Long collectionMethod=new Long(data.get("collectionMethod").toString());
			  String outTradeNo=data.get("outTradeNo").toString();
			  Double refundFee= ArithSolve.formatDoubleScaleFive(new Double(data.get("refundFee").toString()), 2);
			  Double totalMoney= ArithSolve.formatDoubleScaleFive(new Double(data.get("totalMoney").toString()), 2);
			  String 	 isVisitor=data.get("isVisitor").toString();
			  String 	 sickId=data.get("sickId").toString();
              String 	op_user_id=	isVisitor+"_"+ sickId;
			  
			  WxTradeUtil wtu =SpringContextUtils.getWxTradeUtil();
		     AlipayTradeUtil at=SpringContextUtils.getAlipayTradeUtil();
			  boolean isRefundOK=false;
			  String jsonDetail="";
			  if(collectionMethod==0){ 
				  WXRefundModel refundModel=new WXRefundModel(outTradeNo, outTradeNo, "CNY", new Double(refundFee*100).toString(), new Double(totalMoney*100).toString(), op_user_id);
				  Map m=wtu.doRefund(refundModel);
				  if(m!=null){
					  try {
						  WxRefundCusReturnModel wrcr=(WxRefundCusReturnModel) BeanToMapUtil.convertMap(WxRefundCusReturnModel.class,m ) ;
						  isRefundOK=wrcr.isOK();
						  jsonDetail=JSON.toJSONString(wrcr);
					  } catch (Exception e) {
						  // TODO Auto-generated catch block
						  e.printStackTrace();
					  } 
					  
				  }
			  }else{
				  JSONObject jo=at.alipayTradeRefund(outTradeNo, refundFee.toString());
				  if(jo!=null){
					  jo=jo.getJSONObject("alipay_trade_precreate_response");
					  AliRefundCusReturnModel arcr=new AliRefundCusReturnModel(); 
					  try {
						BeanUtils.copyProperties(arcr, jo);
						isRefundOK=arcr.isOK();
						  jsonDetail=JSON.toJSONString(arcr);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				  }
				  
			  }
			  
			  if(isRefundOK){
				  
				  ShopsThirdGoodsRefund stgr=(ShopsThirdGoodsRefund) this.findBySqlUniqueObject("select * from "+this.tableName(ShopsThirdGoodsRefund.class)+" where  id_="+refundId+"", ShopsThirdGoodsRefund.class, null);
				  if(stgr.getRefundStatus()!=4){
					  stgr.setRefundStatus(2);
					  this.updateObject(stgr);
				  }
				  
				  GoodsOrders go=(GoodsOrders) this.findBySqlUniqueObject("select * from "+this.tableName(GoodsOrders.class)+" where  id_="+ordersId+"", GoodsOrders.class, null);
				  if(go.getOrdersStatus()!=6){
					  go.setOrdersStatus(5);
					  this.updateObject(go);
					  
					  ShopsThirdPayOrderRecord stpor=new ShopsThirdPayOrderRecord();
					  stpor.setJsonDetail(jsonDetail);
					  stpor.setPayMethod(collectionMethod.intValue());
					  stpor.setOrdersStatus(4);
					  stpor.setOutTradeNo(outTradeNo);
					  this.saveObject(stpor);
				  }
				  
				
				  return R.ok();
				  
			  }else{
				  R.error("退款失败");
			  }
		  }else{
			  
			  return R.error("无数据");
			  
		  }
		  return R.ok();
		
	 
	}
	@Transactional(propagation = Propagation.REQUIRED,timeout=36000,rollbackFor=Exception.class)
	public R orderRefund(Long orderId,Long userId) {
		String sql=" SELECT stpo.id_ shopsThirdPayOrderId,stpo.totalMoney,stpo.outTradeNo, stpo.collectionMethod,go.ordersStatus,gor.goodsTypeId,gor.goodsName,go.id_ ordersId,go.goodsTotalMoney,go.lastTotalMoney,go.isVisitor,go.sickId,go.outOrderNo,go.receiveAddressFull,go.receiveMobileNO,"
				+ " go.receiveName, gor.goodsId, gor.goodsNum, gor.price, sp.name spName FROM t_txby_sp_goodsOrdersRelation gor INNER JOIN t_txby_sp_goodsOrders go ON go.id_ = gor.ordersId INNER JOIN t_txby_sp_shopsThirdPayOrderRelation stpor INNER JOIN t_txby_sp_shopsThirdPayOrder stpo ON stpor.shopsThirdPayOrderId = stpo.id_"
				+ " AND stpor.ordersId = go.id_  INNER JOIN t_txby_sp_shops sp ON sp.id_ = gor.shopsId INNER JOIN sys_dept d ON d.dept_id = sp.deptId WHERE go.id_="+orderId+" ";
		Map data=(Map) this.findBySqlUniqueObject(sql, null, null);
		if(data!=null){
			Long ordersId=new Long(data.get("ordersId").toString());
			Long shopsThirdPayOrderId=new Long(data.get("shopsThirdPayOrderId").toString());
			Long collectionMethod=new Long(data.get("collectionMethod").toString());
			String outTradeNo=data.get("outTradeNo").toString();
			Double lastTotalMoney= ArithSolve.formatDoubleScaleFive(new Double(data.get("lastTotalMoney").toString()), 2);
			Double totalMoney= ArithSolve.formatDoubleScaleFive(new Double(data.get("totalMoney").toString()), 2);
			String 	 isVisitor=data.get("isVisitor").toString();
			String 	 sickId=data.get("sickId").toString();
			String 	op_user_id=	isVisitor+"_"+ sickId;
			
			WxTradeUtil wtu =SpringContextUtils.getWxTradeUtil();
			AlipayTradeUtil at=SpringContextUtils.getAlipayTradeUtil();
			boolean isRefundOK=false;
			String jsonDetail="";
			if(collectionMethod==0){ 
				WXRefundModel refundModel=new WXRefundModel(outTradeNo, outTradeNo, "CNY", new Long(new Double(lastTotalMoney*100).longValue()).toString(), new Long(new Double(totalMoney*100).longValue()).toString(), op_user_id);
				Map m=wtu.doRefund(refundModel);
				if(m!=null){
					try {
						WxRefundCusReturnModel wrcr=(WxRefundCusReturnModel) BeanToMapUtil.convertMap(WxRefundCusReturnModel.class,m ) ;
//						BeanUtils.copyProperties(wrcr, m);
						wrcr=(WxRefundCusReturnModel) BeanToMapUtil.convertMap(WxRefundCusReturnModel.class, m);
						if(wrcr.getResult_code().equals("SUCCESS")){
							wrcr.setOK(true);
							isRefundOK=true;
						}
						jsonDetail=JSON.toJSONString(m);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} 
					
				}
			}else{
				 AlipayTradeRefundModel model = new AlipayTradeRefundModel();
					model.setOutTradeNo(outTradeNo);
					model.setRefundAmount(lastTotalMoney.toString());
					String requestNo;
					try {
						requestNo = MakeOrderNumUtil.getOrderIdByUUId();
						model.setOutRequestNo(requestNo);
					} catch (ParseException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				JSONObject jo=at.alipayTradeRefund(model);
				if(jo!=null){
					jo=jo.getJSONObject("alipay_trade_refund_response");
					AliRefundCusReturnModel arcr=new AliRefundCusReturnModel(); 
					try {
//						Map m=jo;
//						arcr=JSON.parseObject(jo.toJSONString(), AliRefundCusReturnModel.class);
						BeanUtils.copyProperties(arcr, jo);
						if(jo.getString("code").equals("10000")){
							arcr.setOK(true);
							isRefundOK=true;
						}
						jsonDetail=JSON.toJSONString(arcr);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
			}
			
			if(isRefundOK){
				GoodsOrders go=(GoodsOrders) this.findBySqlUniqueObject("select * from "+this.tableName(GoodsOrders.class)+" where  id_="+ordersId+"", GoodsOrders.class, null);
				if(go.getOrdersStatus()!=6){
					go.setOrdersStatus(5);
					this.updateObject(go);
					ShopsThirdPayOrderRecord stpor=new ShopsThirdPayOrderRecord();
					stpor.setJsonDetail(jsonDetail);
					stpor.setPayMethod(collectionMethod.intValue());
					stpor.setOrdersStatus(4);
					stpor.setOutTradeNo(outTradeNo);
					stpor.setCreater("webRefundOrder-"+userId);
					stpor.setUpdater("webRefundOrder-"+userId);
					this.saveObject(stpor);
				}
				ShopsThirdGoodsRefund stgr=(ShopsThirdGoodsRefund) this.findBySqlUniqueObject("select * from "+this.tableName(ShopsThirdGoodsRefund.class)+" where  shopsThirdPayOrderId="+shopsThirdPayOrderId+" and ordersId="+ordersId+" ", ShopsThirdGoodsRefund.class, null);
				if(stgr!=null){
					if(stgr.getRefundStatus()!=4){
						stgr.setRefundStatus(2);
						this.updateObject(stgr);
					}
				}else{
					stgr=new ShopsThirdGoodsRefund();
					stgr.setOrdersId(ordersId);
					stgr.setRefundFee(lastTotalMoney);
					stgr.setRefundStatus(2);
					stgr.setShopsThirdPayOrderId(shopsThirdPayOrderId);
					stgr.setStatus(0);
					stgr.setCreater("webRefundOrder-"+userId);
					stgr.setUpdater("webRefundOrder-"+userId);
					this.saveObject(stgr);
				}
				
				return R.ok();
				
			}else{
				return R.error("失败,可能交易取消或关闭，请刷新重试");
			}
		}else{
			
			return R.error("无数据");
			
		}
		
		
	}
	@Transactional(propagation = Propagation.REQUIRED,timeout=36000,rollbackFor=Exception.class)
	public R orderCancel(Long orderId,Long userId){
		String sql="  SELECT * FROM  t_txby_sp_goodsOrders go WHERE go.ordersStatus=0 and  go.id_="+orderId+" ";
		GoodsOrders go=(GoodsOrders) this.findBySqlUniqueObject(sql, GoodsOrders.class, null);
		  sql="  SELECT stpo.* FROM t_txby_sp_shopsThirdPayOrderRelation stor, t_txby_sp_shopsThirdPayOrder stpo WHERE stor.shopsThirdPayOrderId = stpo.id_ and stpo.ordersId="+orderId+"";
		  ShopsThirdPayOrder stpo=(ShopsThirdPayOrder) this.findBySqlUniqueObject(sql, ShopsThirdPayOrder.class, null);
		if(go!=null){
			go.setOrdersStatus(3);
			this.updateObject(go);
		}
		Integer retun_result=-1;
		Map   payResult=null;
		 
		if(stpo!=null){
			  try {
				payResult=payCancelQuery(stpo.getOutTradeNo(), stpo.getCollectionMethod(),false,true);
				retun_result=(Integer) payResult.get("result");
				if(retun_result==1){
					 R.error("此订单已经付款或关闭，请刷新重试");
				}else if(retun_result==-1){
					 R.error("此订单请刷新重试");
				}else{
					stpo.setPayStatus(3);
					stpo.setUpdater("webCancelOrder-"+userId);
					this.updateObject(stpo);
					
				}
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
	}
		return R.ok();
		
	}
	
	

	/**
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * 
	* @Title: payCancel 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param outTradeNo
	* @param @param payMethod
	* @param @return    设定文件 
	* @return boolean    返回类型 
	* @throws
	 */
	public Map  payCancelQuery(String outTradeNo,int payMethod,boolean isQuery,boolean isHand) throws Exception{
		Map data=new HashMap();
		Map temp=new HashMap();
		Integer result=-1;
		data.put("result", result);
		data.put("data", temp);
		 try {
			if(payMethod==0){
				 //查询状态
					Map callData = SpringContextUtils.getWxTradeUtil().doOrderQuery(outTradeNo);
					WxOrderQueryCusReturnModel wqc = new WxOrderQueryCusReturnModel();
					if(callData!=null){
						if(isQuery){
							if(wqc.getTrade_state()!=null&&!wqc.getTrade_state().equals("NOTPAY")){
								if(wqc.getTrade_state().equals("SUCCESS")){
									data.put("result", 1);
									data.put("data", callData);
								}else{
									 data.put("result", 40004);
									 data.put("data", callData);
								}
								return data;
							}else{
								 data.put("result", 40004);
								 data.put("data", callData);
								return data;
							}
							
						} 
						BeanUtils.copyProperties(wqc, callData);
						if(wqc.getTrade_state()!=null&&wqc.getTrade_state().equals("NOTPAY")){
							SpringContextUtils.getWxTradeUtil().doOrderClose(outTradeNo);
							ShopsThirdPayOrderRecord stpor =new ShopsThirdPayOrderRecord();
							stpor.setCreater("handWebCancelOrder");
							stpor.setUpdater("handWebCancelOrder");
							stpor.setOrdersStatus(0);
							stpor.setOutTradeNo(outTradeNo);
							stpor.setPayMethod(payMethod);
							stpor.setJsonDetail(JSON.toJSONString(callData));
							 this.saveObject(stpor);
							 data.put("result", 40004);
							 data.put("data", callData);
							 return data;
						}else  if(wqc.getTrade_state()!=null&&!wqc.getTrade_state().equals("NOTPAY")){
							 if(isHand){
								 data.put("result", 1);
								 data.put("data", callData);
							 }else if(wqc.getTrade_state().equals("SUCCESS")){
									data.put("result", 1);
									data.put("data", callData);
							} else {
								 data.put("result", 40004);
								 data.put("data", callData);
							 }
							 return data;
						}
					}
					result=0;
			 }else{
					AliOrderQueryCusReturnModel aqc = new AliOrderQueryCusReturnModel();
					JSONObject jo = SpringContextUtils.getAlipayTradeUtil().alipayTradeQuery(outTradeNo);
					if(jo!=null){
						jo=jo.getJSONObject("alipay_trade_query_response");
						if(isQuery){
							if(aqc.getCode()!=null&&aqc.getCode().equals("10000")&&aqc.getTrade_status()!=null&&!aqc.getTrade_status().equals("WAIT_BUYER_PAY")){
							  if(aqc.getTrade_status().equals("TRADE_SUCCESS")){
									data.put("result", 1);
									data.put("data", jo);
								}else{
									data.put("result", 40004);
									data.put("data", jo);
								}
								return data;
								
							} else{
								data.put("result", 40004);
								data.put("data", jo);
								return data;
							}
							
						}
						BeanUtils.copyProperties(aqc, jo);
						if(aqc.getCode()!=null&&aqc.getCode().equals("10000")&&aqc.getTrade_status()!=null&&aqc.getTrade_status().equals("WAIT_BUYER_PAY")){
							 SpringContextUtils.getAlipayTradeUtil().alipayTradeCancel(outTradeNo);
							 ShopsThirdPayOrderRecord stpor =new ShopsThirdPayOrderRecord();
								stpor.setCreater("handWebCancelOrder");
								stpor.setUpdater("handWebCancelOrder");
								stpor.setOrdersStatus(0);
								stpor.setOutTradeNo(outTradeNo);
								stpor.setPayMethod(payMethod);
								stpor.setJsonDetail(JSON.toJSONString(jo));
								 this.saveObject(stpor);
									 data.put("result", 40004);
									 data.put("data", jo);
								
							 return data;
						}else  if(aqc.getCode()!=null&&aqc.getCode().equals("10000")&&aqc.getTrade_status()!=null&&!aqc.getTrade_status().equals("WAIT_BUYER_PAY")){
							if(isHand){
								data.put("result", 1);
								data.put("data", jo);
							}else if(aqc.getTrade_status().equals("TRADE_SUCCESS")){
								data.put("result", 1);
								data.put("data", jo);
							} else{
								data.put("result", 40004);
								data.put("data", jo);
							}
							 return data;
						} else if(aqc.getCode()!=null&&aqc.getCode().equals("40004")){
							data.put("result", 40004);
							data.put("data", jo);
							 return data;
						} 
					}
			 }
			result=0;
		} catch (Exception e) {
			e.printStackTrace();
			if(payMethod==0){
				 //查询状态
					Map callData = SpringContextUtils.getWxTradeUtil().doOrderQuery(outTradeNo);
					WxOrderQueryCusReturnModel wqc = new WxOrderQueryCusReturnModel();
					if(callData!=null){
						BeanUtils.copyProperties(wqc, callData);
						if(isQuery){
							if(wqc.getTrade_state()!=null&&!wqc.getTrade_state().equals("NOTPAY")){
								data.put("result", 2);
								data.put("data", callData);
								return data;
							}else{
								 data.put("result", 1);
									data.put("data", callData);
								return data;
							}
							
						} 
					
						if(wqc.getTrade_state()!=null&&wqc.getTrade_state().equals("NOTPAY")){
							SpringContextUtils.getWxTradeUtil().doOrderClose(outTradeNo);
							ShopsThirdPayOrderRecord stpor =new ShopsThirdPayOrderRecord();
							stpor.setCreater("handWebCancelOrder");
							stpor.setUpdater("handWebCancelOrder");
							stpor.setOrdersStatus(0);
							stpor.setOutTradeNo(outTradeNo);
							stpor.setPayMethod(payMethod);
							stpor.setJsonDetail(JSON.toJSONString(callData));
							 this.saveObject(stpor);
							 data.put("result", 1);
								data.put("data", callData);
							 return data;
						}else  if(wqc.getTrade_state()!=null&&!wqc.getTrade_state().equals("NOTPAY")){
							data.put("result", 1);
							data.put("data", callData);
							 return data;
						}
					}
			 }else{
					AliOrderQueryCusReturnModel aqc = new AliOrderQueryCusReturnModel();
					JSONObject jo = SpringContextUtils.getAlipayTradeUtil().alipayTradeQuery(outTradeNo);
					if(jo!=null){
						jo=jo.getJSONObject("alipay_trade_query_response");
						BeanUtils.copyProperties(aqc, jo);
						if(isQuery){
							if(aqc.getCode()!=null&&aqc.getCode().equals("10000")&&aqc.getTrade_status()!=null&&!aqc.getTrade_status().equals("WAIT_BUYER_PAY")){
								data.put("result", 2);
								data.put("data", jo);
								return data;
								
							}else{
								data.put("result", 1);
								data.put("data", jo);
								return data;
							}
							
						}
					
						if(aqc.getCode()!=null&&aqc.getCode().equals("10000")&&aqc.getTrade_status()!=null&&aqc.getTrade_status().equals("WAIT_BUYER_PAY")){
							 SpringContextUtils.getAlipayTradeUtil().alipayTradeCancel(outTradeNo);
							 ShopsThirdPayOrderRecord stpor =new ShopsThirdPayOrderRecord();
								stpor.setCreater("handWebCancelOrder");
								stpor.setUpdater("handWebCancelOrder");
								stpor.setOrdersStatus(0);
								stpor.setOutTradeNo(outTradeNo);
								stpor.setPayMethod(payMethod);
								stpor.setJsonDetail(JSON.toJSONString(jo));
								 this.saveObject(stpor);
								 data.put("result", 1);
									data.put("data", jo);
							 return data;
						}else  if(aqc.getCode()!=null&&aqc.getCode().equals("10000")&&aqc.getTrade_status()!=null&&!aqc.getTrade_status().equals("WAIT_BUYER_PAY")){
							data.put("result", 1);
							data.put("data", jo);
							 return data;
						}else if(aqc.getCode()!=null&&aqc.getCode().equals("40004")){
							data.put("result", 40004);
							data.put("data", jo);
							 return data;
						} 
					}
			 }
			result=0;
		}
		
		return data;
	}
	
	 
}
